﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BotvaBot.RequestChains;
using HttpRequester;
using HttpRequester.RequestMakers.Base;
using Helpers;
using System.Text.RegularExpressions;
using System.Net;
using System.Reflection;
using HtmlParsing.Helpers;
using BotvaBot.RequestChains.Base;

namespace BotvaBot.RequestChainItems.Base
{
    public class ExtendedChainItenBase : RequestChainItemBase<RequestManagerPlaneHtml, BotvaChainBase, BotvaChainContext>
    {
        protected override bool IsContextValidInternal()
        {
            bool result = true;

            MethodInfo currentMethod = this.GetType().GetMethod("IsContextValidInternal"
                , BindingFlags.NonPublic | BindingFlags.Instance);
            
            if(ReflectionHelper.HasAttribute<ValidateEmptyContentAttribute>(currentMethod, true))
            {
                result &= !StringHelper.IsnullOrBlank(Chain.LastContent);
                if(!result)
                {
                    InvokationInfo.AddError("Previous request returned empty content");
                }
            }

            if(!result)
                return result;

            ValidateCookieAttribute[] validateCookieAttributes = ReflectionHelper.GetAttributes<ValidateCookieAttribute>(
                currentMethod, true);
            if (!CollectionHelper.IsNullOrEmpty(validateCookieAttributes))
            {
                foreach(var validateCookieAttribute in validateCookieAttributes)
                {
                    result &= Chain.Context.InputCookies.Keys.Contains(validateCookieAttribute.Name);
                    if (!result)
                    {
                        InvokationInfo.AddError(String.Format("Cookie with name {0} was not found atr the Context", validateCookieAttribute.Name));
                        break;
                    }

                    Cookie cookie = Chain.Context.InputCookies[validateCookieAttribute.Name];
                    result &= cookie != null;
                    if(!result)
                    {
                        InvokationInfo.AddError(String.Format("Cookie with name {0} is null", validateCookieAttribute.Name));
                        break;
                    }

                    string cookieValue = cookie.Value;
                    result &= cookieValue != null;
                    if(!result)
                    {
                        InvokationInfo.AddError(String.Format("Cookie with name {0} has null value", validateCookieAttribute.Name));
                        break;
                    }

                    if(StringHelper.IsnullOrBlank(validateCookieAttribute.RegexPattern))
                        continue;
                    
                    Regex re = new Regex(validateCookieAttribute.RegexPattern);
                    result &= re.IsMatch(cookieValue);
                    if(!result)
                    {
                        InvokationInfo.AddError(String.Format("Cookie with name {0} has incorrect value {1}", validateCookieAttribute.Name, cookieValue));
                        break;
                    }
                };
            }

            if(!result)
                return result;

            ValidatePageTitleAttribute validatePageTitleAttribute = ReflectionHelper.GetFirstAttribute<ValidatePageTitleAttribute>(
                currentMethod, true);
            if(validatePageTitleAttribute != null)
            {
                result &= !StringHelper.IsnullOrBlank(Chain.LastContent);
                if(!result)
                {
                    InvokationInfo.AddError("Previous request returned empty content");
                }
                else
                {
                    HtmlParsingHelper htmlHelper = new HtmlParsingHelper(Chain.LastContent);
                    string title = htmlHelper.GetTitle();
                    result &= !StringHelper.IsnullOrBlank(title);
                    if(!result)
                    {
                        InvokationInfo.AddError("Previous request returned content with empty title");
                    }
                    else
                    {
                        result &= StringHelper.IsContains(title, validatePageTitleAttribute.Title,
                            StringCompareModifications.RemoveCase, 
                            StringCompareModifications.RemoveDoubleSpaces, 
                            StringCompareModifications.RemovenewLines);
                        if(!result)
                        {
                            InvokationInfo.AddError(String.Format("Previous request returned content with wrong title : {0}", title));
                        }
                    }
                }
            }

            if(!result)
                return result;

            return result;
        }
    }
}
